home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Graphics Programming (2nd Edition) / Visual Basic Graphics Programming 2nd Edition.iso / Src / Ch18 / M3Ops.bas < prev    next >
BASIC Source File  |  1999-07-10  |  17KB  |  576 lines

  1. Attribute VB_Name = "M3Ops"
  2. Option Explicit
  3.  
  4. Public Const PI = 3.14159265358979
  5. Public Const INFINITY = 2147483647
  6.  
  7. Public Const m3Parallel = 0
  8. Public Const m3Perspective = 1
  9.  
  10. Public Type Point3D
  11.     coord(1 To 4) As Single
  12.     trans(1 To 4) As Single
  13. End Type
  14.  
  15. Public Type Segment3D
  16.     pt1 As Integer
  17.     pt2 As Integer
  18. End Type
  19. ' Convert the spherical coordinates into
  20. ' Cartesian coordinates.
  21. Public Sub m3SphericalToCartesian(ByVal R As Single, ByVal theta As Single, ByVal phi As Single, ByRef X As Single, ByRef Y As Single, ByRef Z As Single)
  22. Dim r2 As Single
  23.     
  24.     ' Create a line to the center of projection.
  25.     Y = R * Sin(phi)
  26.     r2 = R * Cos(phi)
  27.     X = r2 * Cos(theta)
  28.     Z = r2 * Sin(theta)
  29. End Sub
  30. ' Create a transformation matrix for an oblique
  31. ' projection onto the X-Y plane.
  32. Public Sub m3ObliqueXY(M() As Single, ByVal S As Single, ByVal theta As Single)
  33.     m3Identity M
  34.     M(3, 1) = -S * Cos(theta)
  35.     M(3, 2) = -S * Sin(theta)
  36.     M(3, 3) = 0
  37. End Sub
  38.  
  39.  
  40. ' Create a transformation matrix for orthographic
  41. ' projection along the X axis.
  42. Public Sub m3OrthoSide(M() As Single)
  43.     m3Identity M
  44.     M(1, 1) = 0
  45.     M(3, 1) = -1
  46.     M(3, 3) = 0
  47. End Sub
  48. ' Create a transformation matrix for orthographic
  49. ' projection along the Y axis.
  50. Public Sub m3OrthoTop(M() As Single)
  51.     m3Identity M
  52.     M(2, 2) = 0
  53.     M(3, 2) = -1
  54.     M(3, 3) = 0
  55. End Sub
  56.  
  57. ' Create a transformation matrix for orthographic
  58. ' projection along the Z axis.
  59. Public Sub m3OrthoFront(M() As Single)
  60.     m3Identity M
  61.     M(3, 3) = 0
  62. End Sub
  63.  
  64. ' Create an identity matrix.
  65. Public Sub m3Identity(M() As Single)
  66. Dim i As Integer
  67. Dim j As Integer
  68.  
  69.     For i = 1 To 4
  70.         For j = 1 To 4
  71.             If i = j Then
  72.                 M(i, j) = 1
  73.             Else
  74.                 M(i, j) = 0
  75.             End If
  76.         Next j
  77.     Next i
  78. End Sub
  79.  
  80. ' Normalize a 3-D point vector.
  81. Public Sub m3NormalizeCoords(ByRef X As Single, ByRef Y As Single, ByRef Z As Single, ByRef S As Single)
  82.     X = X / S
  83.     Y = Y / S
  84.     Z = Z / S
  85.     S = 1
  86. End Sub
  87.  
  88. ' Normalize a 3-D point vector.
  89. Public Sub m3NormalizePoint(P() As Single)
  90. Dim i As Integer
  91. Dim value As Single
  92.  
  93.     value = P(4)
  94.     For i = 1 To 3
  95.         P(i) = P(i) / value
  96.     Next i
  97.     P(4) = 1
  98. End Sub
  99.  
  100.  
  101. ' Normalize a 3-D transformation matrix.
  102. Public Sub m3NormalizeMatrix(M() As Single)
  103. Dim i As Integer
  104. Dim j As Integer
  105. Dim value As Single
  106.  
  107.     value = M(4, 4)
  108.     For i = 1 To 4
  109.         For j = 1 To 4
  110.             M(i, j) = M(i, j) / value
  111.         Next j
  112.     Next i
  113. End Sub
  114.  
  115.  
  116.  
  117.  
  118. ' Create a 3-D transformation matrix for a
  119. ' perspective projection along the Z axis onto
  120. ' the X-Y plane with focus at the origin and the
  121. ' center of projection at distance (0, 0, D).
  122. Public Sub m3PerspectiveXZ(M() As Single, ByVal D As Single)
  123.     m3Identity M
  124.     If D <> 0 Then M(3, 4) = -1 / D
  125. End Sub
  126.  
  127. ' Create a 3-D transformation matrix for a
  128. ' projection with:
  129. '       center of projection    (cx, cy, cz)
  130. '       focus                   (fx, fy, fx)
  131. '       UP vector               <ux, yx, uz>
  132. ' ptype should be m3Perspective or m3Parallel.
  133. Public Sub m3Project(M() As Single, ByVal ptype As Integer, ByVal Cx As Single, ByVal Cy As Single, ByVal Cz As Single, ByVal Fx As Single, ByVal Fy As Single, ByVal Fz As Single, ByVal ux As Single, ByVal uy As Single, ByVal uz As Single)
  134. Static M1(1 To 4, 1 To 4) As Single
  135. Static M2(1 To 4, 1 To 4) As Single
  136. Static M3(1 To 4, 1 To 4) As Single
  137. Static M4(1 To 4, 1 To 4) As Single
  138. Static M5(1 To 4, 1 To 4) As Single
  139. Static M12(1 To 4, 1 To 4) As Single
  140. Static M34(1 To 4, 1 To 4) As Single
  141. Static M1234(1 To 4, 1 To 4) As Single
  142. Dim sin1 As Single
  143. Dim cos1 As Single
  144. Dim sin2 As Single
  145. Dim cos2 As Single
  146. Dim sin3 As Single
  147. Dim cos3 As Single
  148. Dim A As Single
  149. Dim B As Single
  150. Dim C As Single
  151. Dim d1 As Single
  152. Dim d2 As Single
  153. Dim d3 As Single
  154. Dim up1(1 To 4) As Single
  155. Dim up2(1 To 4) As Single
  156.  
  157.     ' Translate the focus to the origin.
  158.     m3Translate M1, -Fx, -Fy, -Fz
  159.  
  160.     A = Cx - Fx
  161.     B = Cy - Fy
  162.     C = Cz - Fz
  163.     d1 = Sqr(A * A + C * C)
  164.     If d1 <> 0 Then
  165.         sin1 = -A / d1
  166.         cos1 = C / d1
  167.     End If
  168.     d2 = Sqr(A * A + B * B + C * C)
  169.     If d2 <> 0 Then
  170.         sin2 = B / d2
  171.         cos2 = d1 / d2
  172.     End If
  173.     
  174.     ' Rotate around the Y axis to place the
  175.     ' center of projection in the Y-Z plane.
  176.     m3Identity M2
  177.     
  178.     ' If d1 = 0 then the center of projection
  179.     ' already lies in the Y axis and thus the Y-Z plane.
  180.     If d1 <> 0 Then
  181.         M2(1, 1) = cos1
  182.         M2(1, 3) = -sin1
  183.         M2(3, 1) = sin1
  184.         M2(3, 3) = cos1
  185.     End If
  186.     
  187.     ' Rotate around the X axis to place the
  188.     ' center of projection in the Z axis.
  189.     m3Identity M3
  190.     
  191.     ' If d2 = 0 then the center of projection
  192.     ' lies at the origin. This makes projection
  193.     ' impossible.
  194.     If d2 <> 0 Then
  195.         M3(2, 2) = cos2
  196.         M3(2, 3) = sin2
  197.         M3(3, 2) = -sin2
  198.         M3(3, 3) = cos2
  199.     End If
  200.     
  201.     ' Apply the rotations to the UP vector.
  202.     up1(1) = ux
  203.     up1(2) = uy
  204.     up1(3) = uz
  205.     up1(4) = 1
  206.     m3Apply up1, M2, up2
  207.     m3Apply up2, M3, up1
  208.  
  209.     ' Rotate around the Z axis to put the UP
  210.     ' vector in the Y-Z plane.
  211.     d3 = Sqr(up1(1) * up1(1) + up1(2) * up1(2))
  212.     m3Identity M4
  213.     
  214.     ' If d3 = 0 then the UP vector is a zero
  215.     ' vector so do nothing.
  216.     If d3 <> 0 Then
  217.         sin3 = up1(1) / d3
  218.         cos3 = up1(2) / d3
  219.         M4(1, 1) = cos3
  220.         M4(1, 2) = sin3
  221.         M4(2, 1) = -sin3
  222.         M4(2, 2) = cos3
  223.     End If
  224.     
  225.     ' Project.
  226.     If ptype = m3Perspective And d2 <> 0 Then
  227.         m3PerspectiveXZ M5, d2
  228.     Else
  229.         m3Identity M5
  230.     End If
  231.  
  232.     ' Combine the transformations.
  233.     m3MatMultiply M12, M1, M2
  234.     m3MatMultiply M34, M3, M4
  235.     m3MatMultiply M1234, M12, M34
  236.     If ptype = m3Perspective Then
  237.         m3MatMultiplyFull M, M1234, M5
  238.     Else
  239.         m3MatMultiply M, M1234, M5
  240.     End If
  241. End Sub
  242.  
  243.  
  244.  
  245. ' Create a 3-D transformation matrix for a
  246. ' perspective projection with:
  247. '       center of projection    (r, phi, theta)
  248. '       focus                   (fx, fy, fx)
  249. '       up vector               <ux, uy, uz>
  250. ' ptype should be m3Perspective or m3Parallel.
  251. Public Sub m3PProject(M() As Single, ByVal ptype As Integer, ByVal R As Single, ByVal phi As Single, ByVal theta As Single, ByVal Fx As Single, ByVal Fy As Single, ByVal Fz As Single, ByVal ux As Single, ByVal uy As Single, ByVal uz As Single)
  252. Dim Cx As Single
  253. Dim Cy As Single
  254. Dim Cz As Single
  255. Dim r2 As Single
  256.  
  257.     ' Convert to Cartesian coordinates.
  258.     Cy = R * Sin(phi)
  259.     r2 = R * Cos(phi)
  260.     Cx = r2 * Cos(theta)
  261.     Cz = r2 * Sin(theta)
  262.     m3Project M, ptype, Cx, Cy, Cz, Fx, Fy, Fz, ux, uy, uz
  263. End Sub
  264.  
  265. ' Create a transformation matrix for reflecting
  266. ' across the plane passing through (p1, p2, p3)
  267. ' with normal vector <n1, n2, n3>.
  268. Public Sub m3Reflect(M() As Single, ByVal p1 As Single, ByVal p2 As Single, ByVal p3 As Single, ByVal n1 As Single, ByVal n2 As Single, ByVal n3 As Single)
  269. Dim T(1 To 4, 1 To 4) As Single     ' Translate.
  270. Dim R1(1 To 4, 1 To 4) As Single    ' Rotate 1.
  271. Dim r2(1 To 4, 1 To 4) As Single    ' Rotate 2.
  272. Dim S(1 To 4, 1 To 4) As Single     ' Reflect.
  273. Dim R2i(1 To 4, 1 To 4) As Single   ' Unrotate 2.
  274. Dim R1i(1 To 4, 1 To 4) As Single   ' Unrotate 1.
  275. Dim Ti(1 To 4, 1 To 4) As Single    ' Untranslate.
  276. Dim D As Single
  277. Dim L As Single
  278. Dim M12(1 To 4, 1 To 4) As Single
  279. Dim M34(1 To 4, 1 To 4) As Single
  280. Dim M1234(1 To 4, 1 To 4) As Single
  281. Dim M56(1 To 4, 1 To 4) As Single
  282. Dim M567(1 To 4, 1 To 4) As Single
  283.  
  284.     ' Translate the plane to the origin.
  285.     m3Translate T, -p1, -p2, -p3
  286.     m3Translate Ti, p1, p2, p3
  287.  
  288.     ' Rotate around Z-axis until the normal is in
  289.     ' the Y-Z plane.
  290.     m3Identity R1
  291.     D = Sqr(n1 * n1 + n2 * n2)
  292.     R1(1, 1) = n2 / D
  293.     R1(1, 2) = n1 / D
  294.     R1(2, 1) = -R1(1, 2)
  295.     R1(2, 2) = R1(1, 1)
  296.     
  297.     m3Identity R1i
  298.     R1i(1, 1) = R1(1, 1)
  299.     R1i(1, 2) = -R1(1, 2)
  300.     R1i(2, 1) = -R1(2, 1)
  301.     R1i(2, 2) = R1(2, 2)
  302.     
  303.     ' Rotate around the X-axis until the normal
  304.     ' lies along the Y axis.
  305.     m3Identity r2
  306.     L = Sqr(n1 * n1 + n2 * n2 + n3 * n3)
  307.     r2(2, 2) = D / L
  308.     r2(2, 3) = -n3 / L
  309.     r2(3, 2) = -r2(2, 3)
  310.     r2(3, 3) = r2(2, 2)
  311.     
  312.     m3Identity R2i
  313.     R2i(2, 2) = r2(2, 2)
  314.     R2i(2, 3) = -r2(2, 3)
  315.     R2i(3, 2) = -r2(3, 2)
  316.     R2i(3, 3) = r2(3, 3)
  317.  
  318.     ' Reflect across the X-Z plane.
  319.     m3Identity S
  320.     S(2, 2) = -1
  321.  
  322.     ' Combine the matrices.
  323.     m3MatMultiply M12, T, R1
  324.     m3MatMultiply M34, r2, S
  325.     m3MatMultiply M1234, M12, M34
  326.     m3MatMultiply M56, R2i, R1i
  327.     m3MatMultiply M567, M56, Ti
  328.     m3MatMultiply M, M1234, M567
  329. End Sub
  330.  
  331.  
  332. ' Create a transformation atrix for rotating
  333. ' through angle theta around a line passing
  334. ' through (p1, p2, p3) in direction <d1, d2, d3>.
  335. ' Theta is measured counterclockwise as you look
  336. ' down the line opposite the line's direction.
  337. Public Sub m3LineRotate(M() As Single, ByVal p1 As Single, ByVal p2 As Single, ByVal p3 As Single, ByVal d1 As Single, ByVal d2 As Single, ByVal d3 As Single, ByVal theta As Single)
  338. Dim T(1 To 4, 1 To 4) As Single     ' Translate.
  339. Dim R1(1 To 4, 1 To 4) As Single    ' Rotate 1.
  340. Dim r2(1 To 4, 1 To 4) As Single    ' Rotate 2.
  341. Dim Rot3(1 To 4, 1 To 4) As Single  ' Rotate.
  342. Dim R2i(1 To 4, 1 To 4) As Single   ' Unrotate 2.
  343. Dim R1i(1 To 4, 1 To 4) As Single   ' Unrotate 1.
  344. Dim Ti(1 To 4, 1 To 4) As Single    ' Untranslate.
  345. Dim D As Single
  346. Dim L As Single
  347. Dim M12(1 To 4, 1 To 4) As Single
  348. Dim M34(1 To 4, 1 To 4) As Single
  349. Dim M1234(1 To 4, 1 To 4) As Single
  350. Dim M56(1 To 4, 1 To 4) As Single
  351. Dim M567(1 To 4, 1 To 4) As Single
  352.  
  353.     ' Translate the plane to the origin.
  354.     m3Translate T, -p1, -p2, -p3
  355.     m3Translate Ti, p1, p2, p3
  356.  
  357.     ' Rotate around Z-axis until the line is in
  358.     ' the Y-Z plane.
  359.     m3Identity R1
  360.     D = Sqr(d1 * d1 + d2 * d2)
  361.     R1(1, 1) = d2 / D
  362.     R1(1, 2) = d1 / D
  363.     R1(2, 1) = -R1(1, 2)
  364.     R1(2, 2) = R1(1, 1)
  365.     
  366.     m3Identity R1i
  367.     R1i(1, 1) = R1(1, 1)
  368.     R1i(1, 2) = -R1(1, 2)
  369.     R1i(2, 1) = -R1(2, 1)
  370.     R1i(2, 2) = R1(2, 2)
  371.     
  372.     ' Rotate around the X-axis until the line
  373.     ' lies along the Y axis.
  374.     m3Identity r2
  375.     L = Sqr(d1 * d1 + d2 * d2 + d3 * d3)
  376.     r2(2, 2) = D / L
  377.     r2(2, 3) = -d3 / L
  378.     r2(3, 2) = -r2(2, 3)
  379.     r2(3, 3) = r2(2, 2)
  380.     
  381.     m3Identity R2i
  382.     R2i(2, 2) = r2(2, 2)
  383.     R2i(2, 3) = -r2(2, 3)
  384.     R2i(3, 2) = -r2(3, 2)
  385.     R2i(3, 3) = r2(3, 3)
  386.  
  387.     ' Rotate around the line (Y axis).
  388.     m3YRotate Rot3, theta
  389.  
  390.     ' Combine the matrices.
  391.     m3MatMultiply M12, T, R1
  392.     m3MatMultiply M34, r2, Rot3
  393.     m3MatMultiply M1234, M12, M34
  394.     m3MatMultiply M56, R2i, R1i
  395.     m3MatMultiply M567, M56, Ti
  396.     m3MatMultiply M, M1234, M567
  397. End Sub
  398.  
  399. ' Create a 3-D transformation matrix for scaling
  400. ' by scale factors Sx, Sy, and Sz.
  401. Public Sub m3Scale(M() As Single, ByVal Sx As Single, ByVal Sy As Single, ByVal Sz As Single)
  402.     m3Identity M
  403.     M(1, 1) = Sx
  404.     M(2, 2) = Sy
  405.     M(3, 3) = Sz
  406. End Sub
  407.  
  408. ' Create a 3-D transformation matrix for
  409. ' translation by Tx, Ty, and Tz.
  410. Public Sub m3Translate(M() As Single, ByVal Tx As Single, ByVal Ty As Single, ByVal Tz As Single)
  411.     m3Identity M
  412.     M(4, 1) = Tx
  413.     M(4, 2) = Ty
  414.     M(4, 3) = Tz
  415. End Sub
  416.  
  417. ' Create a 3-D transformation matrix for rotation
  418. ' around the X axis (angle measured in radians).
  419. Public Sub m3XRotate(M() As Single, ByVal theta As Single)
  420.     m3Identity M
  421.     M(2, 2) = Cos(theta)
  422.     M(3, 3) = M(2, 2)
  423.     M(2, 3) = Sin(theta)
  424.     M(3, 2) = -M(2, 3)
  425. End Sub
  426.  
  427. ' Create a 3-D transformation matrix for rotation
  428. ' around the Y axis (angle measured in radians).
  429. Public Sub m3YRotate(M() As Single, ByVal theta As Single)
  430.     m3Identity M
  431.     M(1, 1) = Cos(theta)
  432.     M(3, 3) = M(1, 1)
  433.     M(3, 1) = Sin(theta)
  434.     M(1, 3) = -M(3, 1)
  435. End Sub
  436.  
  437. ' Create a 3-D transformation matrix for rotation
  438. ' around the Z axis (angle measured in radians).
  439. Public Sub m3ZRotate(M() As Single, ByVal theta As Single)
  440.     m3Identity M
  441.     M(1, 1) = Cos(theta)
  442.     M(2, 2) = M(1, 1)
  443.     M(1, 2) = Sin(theta)
  444.     M(2, 1) = -M(1, 2)
  445. End Sub
  446.  
  447. ' Create a matrix that rotates around the Y axis
  448. ' so the point (x, y, z) lies in the X-Z plane.
  449. Public Sub m3YRotateIntoXZ(Result() As Single, ByVal X As Single, ByVal Y As Single, ByVal Z As Single)
  450. Dim D As Single
  451.  
  452.     m3Identity Result
  453.     D = Sqr(X * X + Y * Y)
  454.     Result(1, 1) = X / D
  455.     Result(1, 2) = -Y / D
  456.     Result(2, 1) = -Result(1, 2)
  457.     Result(2, 2) = Result(1, 1)
  458. End Sub
  459.  
  460. ' Set copy = orig.
  461. Public Sub m3MatCopy(copy() As Single, orig() As Single)
  462. Dim i As Integer
  463. Dim j As Integer
  464.  
  465.     For i = 1 To 4
  466.         For j = 1 To 4
  467.             copy(i, j) = orig(i, j)
  468.         Next j
  469.     Next i
  470. End Sub
  471.  
  472. ' Apply a transformation matrix to a point where
  473. ' the transformation may not have 0, 0, 0, 1 in
  474. ' its final column. Normalize only the X and Y
  475. ' components of the result to preserve the Z
  476. ' information.
  477. Public Sub m3ApplyFull(V() As Single, M() As Single, Result() As Single)
  478. Dim i As Integer
  479. Dim j As Integer
  480. Dim value As Single
  481.  
  482.     For i = 1 To 4
  483.         value = 0#
  484.         For j = 1 To 4
  485.             value = value + V(j) * M(j, i)
  486.         Next j
  487.         Result(i) = value
  488.     Next i
  489.     
  490.     ' Renormalize the point.
  491.     ' Note that value still holds Result(4).
  492.     If value <> 0 Then
  493.         Result(1) = Result(1) / value
  494.         Result(2) = Result(2) / value
  495.         ' Do not transform the Z component.
  496.     Else
  497.         ' Make the Z value greater than that of
  498.         ' the center of projection so the point
  499.         ' will be clipped.
  500.         Result(3) = INFINITY
  501.     End If
  502.     Result(4) = 1#
  503. End Sub
  504.  
  505.  
  506.  
  507.  
  508. ' Apply a transformation matrix to a point.
  509. Public Sub m3Apply(V() As Single, M() As Single, Result() As Single)
  510.     Result(1) = V(1) * M(1, 1) + _
  511.                 V(2) * M(2, 1) + _
  512.                 V(3) * M(3, 1) + M(4, 1)
  513.     Result(2) = V(1) * M(1, 2) + _
  514.                 V(2) * M(2, 2) + _
  515.                 V(3) * M(3, 2) + M(4, 2)
  516.     Result(3) = V(1) * M(1, 3) + _
  517.                 V(2) * M(2, 3) + _
  518.                 V(3) * M(3, 3) + M(4, 3)
  519.     Result(4) = 1#
  520. End Sub
  521.  
  522. ' Multiply two matrices together. The matrices
  523. ' may not contain 0, 0, 0, 1 in their last
  524. ' columns.
  525. Public Sub m3MatMultiplyFull(Result() As Single, A() As Single, B() As Single)
  526. Dim i As Integer
  527. Dim j As Integer
  528. Dim k As Integer
  529. Dim value As Single
  530.  
  531.     For i = 1 To 4
  532.         For j = 1 To 4
  533.             value = 0#
  534.             For k = 1 To 4
  535.                 value = value + A(i, k) * B(k, j)
  536.             Next k
  537.             Result(i, j) = value
  538.         Next j
  539.     Next i
  540. End Sub
  541. ' Multiply two matrices together.
  542. Public Sub m3MatMultiply(Result() As Single, A() As Single, B() As Single)
  543.     Result(1, 1) = A(1, 1) * B(1, 1) + A(1, 2) * B(2, 1) + A(1, 3) * B(3, 1)
  544.     Result(1, 2) = A(1, 1) * B(1, 2) + A(1, 2) * B(2, 2) + A(1, 3) * B(3, 2)
  545.     Result(1, 3) = A(1, 1) * B(1, 3) + A(1, 2) * B(2, 3) + A(1, 3) * B(3, 3)
  546.     Result(1, 4) = 0#
  547.     Result(2, 1) = A(2, 1) * B(1, 1) + A(2, 2) * B(2, 1) + A(2, 3) * B(3, 1)
  548.     Result(2, 2) = A(2, 1) * B(1, 2) + A(2, 2) * B(2, 2) + A(2, 3) * B(3, 2)
  549.     Result(2, 3) = A(2, 1) * B(1, 3) + A(2, 2) * B(2, 3) + A(2, 3) * B(3, 3)
  550.     Result(2, 4) = 0#
  551.     Result(3, 1) = A(3, 1) * B(1, 1) + A(3, 2) * B(2, 1) + A(3, 3) * B(3, 1)
  552.     Result(3, 2) = A(3, 1) * B(1, 2) + A(3, 2) * B(2, 2) + A(3, 3) * B(3, 2)
  553.     Result(3, 3) = A(3, 1) * B(1, 3) + A(3, 2) * B(2, 3) + A(3, 3) * B(3, 3)
  554.     Result(3, 4) = 0#
  555.     Result(4, 1) = A(4, 1) * B(1, 1) + A(4, 2) * B(2, 1) + A(4, 3) * B(3, 1) + B(4, 1)
  556.     Result(4, 2) = A(4, 1) * B(1, 2) + A(4, 2) * B(2, 2) + A(4, 3) * B(3, 2) + B(4, 2)
  557.     Result(4, 3) = A(4, 1) * B(1, 3) + A(4, 2) * B(2, 3) + A(4, 3) * B(3, 3) + B(4, 3)
  558.     Result(4, 4) = 1#
  559. End Sub
  560.  
  561. ' Compute the cross product of two vectors.
  562. ' Set <X, Y, Z> = <x1, y1, z1> X <x2, y2, z2>.
  563. Public Sub m3Cross(ByRef X As Single, ByRef Y As Single, ByRef Z As Single, ByVal x1 As Single, ByVal y1 As Single, ByVal z1 As Single, ByVal x2 As Single, ByVal y2 As Single, ByVal z2 As Single)
  564.     X = y1 * z2 - z1 * y2
  565.     Y = z1 * x2 - x1 * z2
  566.     Z = x1 * y2 - y1 * x2
  567. End Sub
  568.  
  569. ' Give the vector the indicated length.
  570. Public Sub m3SizeVector(ByVal L As Single, ByRef X As Single, ByRef Y As Single, ByRef Z As Single)
  571.     L = L / Sqr(X * X + Y * Y + Z * Z)
  572.     X = X * L
  573.     Y = Y * L
  574.     Z = Z * L
  575. End Sub
  576.